package server;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;

import main.logParser;

public class LogServer {
	private static ArrayList<Socket> clientList = new ArrayList<Socket>();
	private static int id = 0;
	private static LogServer me;

	/**
	 * Singleton pattern so only one instance of a LogServer can exist.
	 */
	private LogServer(){
		
	}
	
	public static LogServer getInstance(){
		if(me != null){
			return me;
		} else {
			me = new LogServer();
		}
		return me;
	}
	
	public void startServer(int inPort) throws IOException{
		// Get the port and created a socket there.
		int port = 13337;
		if (inPort > 0)
			port = inPort;
		
		ServerSocket listener = new ServerSocket(port);
		System.out.println("The Log Server is running on port " + port);

		// Listen for clients. Start a new handler for each.
		// Add each client to the linked list.
		while (true) {
			Socket client = listener.accept();
			new LogHandler(client).start();
			System.out.println("New client no." + id + " on client's port "
					+ client.getPort());
			clientList.add(client);
			id++;
		}
	}

	static synchronized void broadcast(String message, String name)
			throws IOException {

		// Sends the message to every client including the sender.
		Socket s;
		PrintWriter p;
		for (int k = 0; k < clientList.size(); k++) {
			s = (Socket) clientList.get(k);
			p = new PrintWriter(s.getOutputStream(), true);
			p.println(name + ": " + message);
		}
	}

	static synchronized void remove(Socket s) {

		// Finds the client on the list (by comparing socket
		// references) and removes it.
		int k;
		Socket t;
		for (k = 0; k < clientList.size(); k++) {
			t = (Socket) clientList.get(k);
			if (t.equals(s))
				break;
		}
		clientList.remove(k);
		id--;
	}
	
	public static void main(String[] args){
		LogServer server = LogServer.getInstance();
		try {
			if(args.length == 0)
				server.startServer(13337);
			else if(args.length == 1){
				try{
					server.startServer(Integer.parseInt(args[0]));
				}catch(Exception e){
					server.startServer(13337);
				}
			}
				
			
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

class LogHandler extends Thread {

	// The Chat Handler class is called from the Chat Server:
	// one thread for each client coming in to chat.

	private BufferedReader in;
	private PrintWriter out;
	private Socket toClient;
	private String name;
	private logParser parser;

	LogHandler(Socket s) {
		toClient = s;
		parser = new logParser();
	}

	public void run() {
		try {
			//Gets a log file from a client.
			in = new BufferedReader(new InputStreamReader((toClient
					.getInputStream())));

			while (true) {
				String s = in.readLine().trim();
				
				parser.stringParse(s);
				
				// Check first three characters for BYE.
				// Avoids problems with different line end characters.
				if (s.charAt(0) == 'B' && s.charAt(1) == 'Y'
						&& s.charAt(2) == 'E') {
					break;
				}
			}
			LogServer.remove(toClient);
			toClient.close();
		} catch (Exception e) {
			System.out.println("Chatter error: " + e);
			LogServer.remove(toClient);
			try {
				toClient.close();
			} catch (IOException e1) {
				e1.printStackTrace();
			}
		}
	}

}
